package com.ishitong.platform.common.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;

import com.ishitong.platform.common.page.Page;


/**
 * 利用范型提供增删改查功能的DAO接口
 */
public interface GenericDaoInterface<SuperClass> extends GenericSQLDaoInterface {
	/**
	 * 通过主键取得实例
	 * 
	 * @param id
	 *            主键
	 * @return 该主键对应的实例
	 */
	SuperClass get(Serializable id);

	/**
	 * 保存实例
	 * 
	 * @param obj
	 *            待保存的实例
	 */
	void save(SuperClass obj);

	/**
	 * 保存实例
	 * 
	 * @param obj
	 *            待保存的实例
	 */
	void saveOnly(SuperClass obj);

	/**
	 * 根据主键删除实例
	 * 
	 * @param id
	 *            带删除实例的主键
	 */
	void remove(Serializable id);

	/**
	 * 删除指定的实例
	 * 
	 * @param obj
	 *            待删除的实例
	 */
	void remove(SuperClass obj);

	/**
	 * 取得和被持久化的EntityClass关联的Criteria实例。
	 * 
	 * @return 持久化类的Criteria对象
	 */
	Criteria getCriteria();

	/**
	 * 通过hql查询记录集。<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.findByCriteria(hql, pageSize, pageNum);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, arg0);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, arg0,arg1);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, new
	 * Object[arg0,arg1,arg2]);
	 * </ul>
	 * pageSize和pageNum必须同时大于0才有效，否则将取出所有符合条件的记录。
	 * 
	 * @param hql
	 *            查询语句
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @param args
	 *            查询语句参数
	 * @return 该页的Page对象
	 * @see com.ishitong.platform.common.page.Page
	 */
	Page findByHql(String hql, int pageSize, int pageNum, Object... args);

	/**
	 * 统计查询语句的结果集大小。<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.count(hql);
	 * <li> dao.count(hql, arg0);
	 * <li> dao.count(hql, arg0, arg1);
	 * <li> dao.count(hql, new Object[arg0,arg1,arg2]);
	 * </ul>
	 * 
	 * @param hql
	 *            查询语句
	 * @param args
	 *            绑定的参数
	 * @return 结果集的大小
	 */
	long count(String hql, Object... args);

	/**
	 * 分页查询函数，使用Criteria.
	 * 
	 * @param criteria
	 *            查询用Criteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 */
	Page findByCriteria(Criteria criteria, int pageSize, int pageNum);

	/**
	 * 取得河北持久化的EntityClass关联的DetachedCriteria。<br>
	 * 此方法供业务层之上的上层代码使用，如Struts的Action类或者JUnit的测试代码。
	 * 
	 * @return 查询对象
	 */
	DetachedCriteria getDetachedCriteria();

	/**
	 * 分页查询函数，使用DetachedCriteria
	 * 
	 * @param dc
	 *            设置好条件的DetachedCriteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 */
	Page findByDetachedCriteria(DetachedCriteria dc, int pageSize, int pageNum);

	/**
	 * 判断对象某几列值的组合在数据库中不存在重复记录
	 * 
	 * @param entity
	 *            实例对象
	 * @param names
	 *            在POJO里相对应的属性名的列表
	 * @return true: 有重复记录，flase: 无重复记录
	 */
	boolean isNotUnique(Object entity, String... names);

	/**
	 * 消除与 Hibernate Session 的关联
	 * 
	 * @param obj
	 *            待操作的实例
	 */
	void evit(SuperClass obj);

	/**
	 * 分页取得所有记录
	 * 
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            待取得页码，从1开始
	 * @param orderBy
	 *            排序字段
	 * @param isAsc
	 *            是否升序，false表示降序
	 * @return 指定页码的记录
	 */
	Page listAll(int pageSize, int pageNum, String orderBy, boolean isAsc);

	/**
	 * 分页查询指定字段的值等于指定值的记录
	 * 
	 * @param fieldName
	 *            字段名称
	 * @param value
	 *            指定的值
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页号，从1开始
	 * @return 指定页的记录
	 */
	Page findByFieldEquals(String fieldName, Object value, int pageSize, int pageNum);

	/**
	 * 通过hql查询记录集。<br>
	 * 此方法不同于findByHQL之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.findByHql(hql, pageSize, pageNum);
	 * <li> dao.findByHql(hql, pageSize, pageNum, arg0);
	 * <li> dao.findByHql(hql, pageSize, pageNum, arg0, arg1);
	 * <li> dao.findByHql(hql, pageSize, pageNum, new Object[arg0, arg1, arg2]);
	 * </ul>
	 * pageSize和pageNum必须同时大于0才有效，否则将取出所有符合条件的记录。
	 * 
	 * @param hql
	 *            查询语句
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @param args
	 *            查询语句参数
	 * @return 该页的Page对象
	 * @see com.ishitong.platform.common.dao.GenericDao#findByHql(String, int,
	 *      int, Object[])
	 */
	List findFastByHql(String hql,  Object... args);

	/**
	 * 分页查询函数，使用Criteria.<br>
	 * 此方法不同于findByCriteria之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 
	 * @param criteria
	 *            查询用Criteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 * @see com.ishitong.platform.common.dao.GenericDao#findByCriteria(org.hibernate.Criteria,
	 *      int, int)
	 */
	List findFastByCriteria(Criteria criteria);

	/**
	 * 分页查询函数，使用DetachedCriteria<br>
	 * 此方法不同于findByDetachedCriteria之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 
	 * @param dc
	 *            设置好条件的DetachedCriteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 * @see com.ishitong.platform.common.dao.GenericDao#findByDetachedCriteria(org.hibernate.criterion.DetachedCriteria,
	 *      int, int)
	 */
	List findFastByDetachedCriteria(DetachedCriteria dc);

	/**
	 * 查询分页数据
	 * 
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	Page find(int pageSize, int pageNum);

	/**
	 * 根据唯一字段值ID查询数据
	 * 
	 * @param id
	 * @return
	 */
	SuperClass findByUniqueKey(String fieldName, Object value);

	/**
	 * 通过主键ID查询数据
	 * 
	 * @param value
	 * @return
	 */
	SuperClass findByPrimaryKey(Object value);

	/**
	 * 执行HQL,返回记录受影响的行数
	 * 
	 * @param hql
	 * @param args
	 * @return
	 */
	int executeByHql(String hql, Object... args);

	/**
	 * 刷新当前session
	 */
	void flushSession();

}
